﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using SmartMeterParamFrame;
using SmartMeterParamFrame.Model;
using Comm.Util;
using Comm.HardDisk;
using Comm.Crypt;
namespace SmartMeterParamSetting
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Communicate comm = null;

        private FACollection faItems;

        //private System.Windows.Media.Effects.BlurEffect effect = new System.Windows.Media.Effects.BlurEffect();

        public MainWindow()
        {
            InitializeComponent();

            //effect.Radius = 5;

            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
        }


        #region ------------------------窗体事件---------------------------------
        /// <summary>
        /// 程序窗体关闭时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if ((bool)Btn_Star.IsChecked)
            {
                MessageBox.Show("项目正在操作中，无法关闭，请先停止项目操作....", "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                e.Cancel = true;
                return;
            }
            if (MessageBox.Show("你确认要关闭本程序么？", "关闭询问", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.Cancel)
            {
                e.Cancel = true;
                return;
            }

            if (comm != null)
            {
                comm.Dispose();
            }
            Application.Current.Shutdown();
        }
        /// <summary>
        /// 程序窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            comm = new Communicate(Mod_Main.systemInfo.MachineAddr, Mod_Main.systemInfo.MachinePort);
            comm.IsYuanCheng = Mod_Main.systemInfo.IsYuanCheng;

            SmartMeterParamFrame.Communicate.IdentityType = Mod_Main.systemInfo.IdentityType;

            LstMeterState.ItemsSource = comm.MeterItems;

            Data_Meter.ItemsSource = comm.MeterItems;

            ShowState();
            LoadScheme("Scheme");

        }

        /// <summary>
        /// 电能表全选或者取消全选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            foreach (MeterInfo item in comm.MeterItems)
            {
                item.CheckYn = (bool)((CheckBox)sender).IsChecked;
            }
        }

        /// <summary>
        /// DATAGRID当前行所对应的表位要检不检的选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RowCheck_Click(object sender, RoutedEventArgs e)
        {
            MeterInfo item = Data_Meter.SelectedItem as MeterInfo;
            if (item == null) return;

            item.CheckYn = (bool)((CheckBox)sender).IsChecked;

        }

        /// <summary>
        /// 工具条按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolBtn_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;

            if (btn.Name.ToLower() != "btn_close" && btn.Name.ToLower() != "btn_about" && btn.Name.ToLower() != "btn_system" && !CheckLicense()) return;

            if ((bool)Btn_Star.IsChecked && btn.Name.ToLower() != "btn_stop") return;

            switch (btn.Name.ToLower())
            {
                case "btn_system":
                    //this.Effect = effect;
                    systemSetting();
                    //this.Effect = null;
                    break;
                case "btn_import":
                    LoadFa();
                    break;
                case "btn_dataview":
                    UI.UI_DataView view = new UI.UI_DataView(comm.MeterItems, faItems);
                    view.ShowDialog();
                    break;
                case "btn_clear":           //数据清理
                    if (comm != null) comm.ClearData();
                    break;
                case "btn_stop":
                    if (!(bool)Btn_Star.IsChecked) return;
                    UI.Waiting uiWaiting = new UI.Waiting();
                    uiWaiting.Show();
                    try
                    {
                        comm.Abort();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "关源出现异常", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    WorkStateButtonSetting(false);
                    uiWaiting.Close();
                    break;
                case "btn_close":
                    this.Close();
                    break;
                case "btn_about":
                    UI.UI_About about = new UI.UI_About();
                    about.ShowDialog();
                    break;
            }
        }
        /// <summary>
        /// 开始检定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolTogBtn_Click(object sender, RoutedEventArgs e)
        {
            if (!CheckLicense())
            {
                this.WorkStateButtonSetting(false);
                return;
            }
            System.Windows.Controls.Primitives.ToggleButton btn = sender as System.Windows.Controls.Primitives.ToggleButton;

            if (btn == null)
            {
                this.WorkStateButtonSetting(false);
                return;
            }
            if (comm == null)
            {
                this.WorkStateButtonSetting(false);
                MessageBox.Show("致命错误，系统加载应用模块失败，请联系相关开发人员...", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (btn.Name.ToLower() == "btn_feikong")
            {
                if ((bool)Btn_Star.IsChecked) return;
                if (!comm.IsMachineReady)
                {
                    MessageBox.Show("加密机尚未联机，无法进行费控累操作...", "错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    btn.IsChecked = false;
                    return;
                }
                Tool_FeiKong.Visibility = (bool)btn.IsChecked ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                return;
            }


            if ((bool)Btn_FeiKong.IsChecked) Btn_FeiKong.IsChecked = false;

            if (Tool_FeiKong.Visibility == System.Windows.Visibility.Visible) Tool_FeiKong.Visibility = System.Windows.Visibility.Collapsed;


            if (!(bool)btn.IsChecked)       //第一次点击进来肯定是选中，但是第二次再点状态就会变为未选中，那么在这处理未选中时，等同于按下后处理不允许取消按下。
            {
                btn.IsChecked = true;
                return;
            }

            //if (!comm.IsDeviceLink)
            //{
            //    MessageBox.Show("装置尚未准备就绪，无法进行操作...", "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            //    btn.IsChecked = false;
            //    return;
            //}

            if (faItems == null || faItems.Count == 0)
            {
                MessageBox.Show("没有可用方案项目，操作自动终止...", "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                btn.IsChecked = false;
                return;
            }

            if (!comm.MeterItems.HaveYaoJian())         //检查表是否存在要检
            {
                btn.IsChecked = false;
                MessageBox.Show("没有需要进行操作的电能表,操作被终止...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            if (!comm.IsMachineReady)           //如果加密机连接失败，还是可以进行参数的设置和核对的。
            {
                if (MessageBox.Show("加密机没有连接成功,请问还要继续操作吗？\r\n点击【确认】继续执行操作，如果有费控类操作将会自动跳过；\r\n点击【取消】终止操作。",
                                    "询问",
                                    MessageBoxButton.OKCancel,
                                    MessageBoxImage.Question) == MessageBoxResult.Cancel)
                {
                    btn.IsChecked = false;
                    return;
                }
            }

            if (!comm.MeterItems.IsNew())
            {
                if (MessageBox.Show("当前要进行操作的电能表模型数据中存在数据记录！\r\n点击【确定】继续操作，点击【取消】停止操作.\r\n停止操作后可点击【清理数据】，将当前电能表数据模型中数据清除，再进行操作。", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.Cancel)
                {
                    btn.IsChecked = false;
                    return;
                }
            }

            UI.UI_Power Power = new UI.UI_Power();

            var uiReturn = Power.ShowDialog();

            if (!(bool)uiReturn)
            {
                btn.IsChecked = false;
                return;
            }
            Lst_PrjItems.IsHitTestVisible = false;
            //将所有失败的操作设置成，没有操作，以便从失败的地方开始设置
            comm.MeterItems.ResetAllUnSuccessToNone();
            comm.StarWork(faItems, Power.PowerValue, ShowWaiting, WorkFinish, ShowFaListMove, ShowKeyDownMessage);
            Power = null;

        }

        /// <summary>
        /// 鼠标选择方案列表事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Lst_PrjItems_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if ((bool)Btn_Star.IsChecked) return;

            FAinfo item = Lst_PrjItems.SelectedItem as FAinfo;

            if (item == null) return;

            comm.MeterItems.SetCurrentProject(item.PrjOrderID, item.PrjName);
        }

        /// <summary>
        /// 费控功能测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_FeiKong_Click(object sender, RoutedEventArgs e)
        {
            FAinfo item = new FAinfo();
            item.ReviewType = EnumCheckType.仅修正;
            item.PrjOrderID = 1;
            item.PrjType = EnumFAType.费控功能;
            item.PrjName = "费控测试-";

            StackPanel sp = ((Button)sender).Content as StackPanel;

            if (sp == null) return;

            string strCaption = "";

            foreach (UIElement ue in sp.Children)
            {
                if (ue is TextBlock)
                {
                    strCaption = ((TextBlock)ue).Text.Replace(" ", "");
                    break;
                }
            }
            switch (strCaption)
            {
                case "拉闸":
                    item.PrjName += EnumUserControl.拉闸.ToString();
                    item.DataDomain = ((int)EnumUserControl.拉闸).ToString();
                    break;
                case "合闸":
                    item.PrjName += EnumUserControl.合闸.ToString();
                    item.DataDomain = ((int)EnumUserControl.合闸).ToString();
                    break;
                case "报警":
                    item.PrjName += EnumUserControl.报警.ToString();
                    item.DataDomain = ((int)EnumUserControl.报警).ToString();
                    break;
                case "取消报警":
                    item.PrjName += EnumUserControl.取消报警.ToString();
                    item.DataDomain = ((int)EnumUserControl.取消报警).ToString();
                    break;
                case "保电":
                    item.PrjName += EnumUserControl.保电.ToString();
                    item.DataDomain = ((int)EnumUserControl.保电).ToString();
                    break;
                case "解除保电":
                    item.PrjName += EnumUserControl.保电解除.ToString();
                    item.DataDomain = ((int)EnumUserControl.保电解除).ToString();
                    break;
                case "密钥下装":
                    item.PrjName = EnumFAType.密钥下装.ToString(); ;
                    item.PrjType = EnumFAType.密钥下装;
                    break;
                default:
                    return;
            }

            faItems.Clear();

            faItems.Add(item);
            Btn_Star.IsChecked = true;

            Btn_FeiKong.IsChecked = false;

            Tool_FeiKong.Visibility = System.Windows.Visibility.Collapsed;
            comm.MeterItems.ClearAllCheckResults();
            ToolTogBtn_Click(Btn_Star, new RoutedEventArgs());
        }


        /// <summary>
        /// 加密机联机按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_LinkMachine_Click(object sender, RoutedEventArgs e)
        {
            if (comm == null) return;

            if (!comm.IsMachineReady)
            {
                comm.SetEncryptMachine(Mod_Main.systemInfo.MachineAddr, Mod_Main.systemInfo.MachinePort);
                ShowState();
            }
        }
        /// <summary>
        /// 驱动联机
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_LinkDevice_Click(object sender, RoutedEventArgs e)
        {
            if (comm == null) return;
            //if (!comm.IsDeviceLink)
            //{
            comm.LinkDevice();
            ShowState();
            //}
        }


        #endregion

        #region ------------Comminucation回调函数----------------

        private static UI.Waiting waiting = null;

        /// <summary>
        /// 回调函数，显示等待UI
        /// </summary>
        /// <param name="s"></param>
        private void ShowWaiting(string s, bool isClose)
        {
            if (waiting == null)
            {
                waiting = new UI.Waiting(s);
                waiting.Show();
                //this.Effect = effect;
            }
            else
            {
                if (isClose)
                {
                    waiting.Close();
                    waiting = null;
                    //this.Effect = null;
                    return;
                }
                waiting.setDescription(s);
            }
        }

        /// <summary>
        /// 回调函数，开始按钮状态改变
        /// </summary>
        private void WorkFinish()
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
                                        {
                                            WorkStateButtonSetting(false);
                                        }));

            MessageBox.Show("方案项目操作完成，请检查结果...", "完成", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        /// <summary>
        /// 回调函数，显示项目列表工作移动
        /// </summary>
        /// <param name="index">方案项目下标</param>
        private void ShowFaListMove(int index)
        {
            this.Dispatcher.Invoke(new Action(() =>
                                              {
                                                  Lst_PrjItems.SelectedItem = faItems[index];
                                                  Lst_PrjItems.ScrollIntoView(faItems[index]);
                                              }));
        }

        /// <summary>
        /// 下装时第一步完成后的消息提示，该函数为下装过程的线程回调函数
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private bool ShowKeyDownMessage(string message)
        {
            message = string.Format("有如下表需要进行本地密钥下装插卡操作，请检查\r\n{0}\r\n点击【确认】继续完成下装，点击【取消】退出下装。", message);

            return MessageBox.Show(message, "下装提示", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK ? true : false;
        }

        #endregion


        #region ------------------Private Method--------------------

        /// <summary>
        /// 许可证验证
        /// </summary>
        /// <returns></returns>
        private bool CheckLicense()
        {
#if !TEST
            if (!Mod_Main.IsLicense)
            {
                MessageBox.Show("系统许可文件没有找到或失效，系统无法执行操作，请点击【关于】按钮，根据提示导入许可文件..", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
#endif
            return true;
        }

        /// <summary>
        /// 工作按钮工作状态设定
        /// </summary>
        /// <param name="isOver"></param>
        private void WorkStateButtonSetting(bool isWorking)
        {
            Btn_Star.IsChecked = isWorking;
            Lst_PrjItems.IsHitTestVisible = !isWorking;
        }

        /// <summary>
        /// 加载方案
        /// </summary>
        private void LoadFa()
        {
            if (System.IO.File.Exists(SchemeUtils.GetFullPath("Scheme")))
            {
                if (MessageBox.Show("发现本地存在方案，请问是从服务器导入方案，还是加载本地方案？\r\n点击【确认】从服务器导入方案，点击【取消】从本地加载方案", "询问", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.Cancel)
                {
                    LoadScheme("Scheme");
                    return;
                }
            }

            try
            {
                SchemesServer.SchemesServerClient client = new SchemesServer.SchemesServerClient();
                client.Endpoint.Address = new System.ServiceModel.EndpointAddress(Mod_Main.systemInfo.FaServer);

                string[] strs = client.GetSchemes();
                if (strs != null && strs.Length != 0)
                {
                    UI.SelectScheme selectBox = new UI.SelectScheme(strs);
                    //this.Effect = effect;
                    bool? diaRet = selectBox.ShowDialog();
                    this.Effect = null;
                    if (!(bool)diaRet) return;
                    try
                    {
                        //byte[] buf = client.GetSchemeContent(selectBox.SelectedScheme, SchemeUtils.WEB_SERVICE_PASSWORD, HardDiskHelper.GetAllHardDiskSN());

                        SchemesServer.DataInfo info = new SchemesServer.DataInfo();

                        info.Name = selectBox.SelectedScheme;

                        info.BuffLen = 1024 * 10;   //10一次
                        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                        {
                            do
                            {
                                info = client.GetSchemeContent(info, SchemeUtils.WEB_SERVICE_PASSWORD, HardDiskHelper.GetAllHardDiskSN());

                                if (info == null)
                                {
                                    MessageBox.Show("从服务器获取方案失败，失败原因：未被许可的客户端接入...", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                                    return;
                                }

                                ms.Write(info.Data, 0, info.Data.Length);

                                info.Offset = ms.Position;

                            } while (info.Offset != info.Length);

                            ////保存到文件
                            string savePath = SchemeUtils.GetFullPath("Scheme");
                            if (SchemeUtils.SaveScheme(HardDiskHelper.GetAllHardDiskSN(), "Scheme", ms.ToArray()) == false)
                            {
                                MessageBox.Show("无法下载方案...", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }

                        //加载到方案中
                        LoadScheme("Scheme");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("方案加载出错，出错原因：" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("方案服务器上没有方案可被下载...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }
        }

        /// <summary>
        /// 系统设置更新
        /// </summary>
        private void systemSetting()
        {
            UI.UI_Config config = new UI.UI_Config();
            config.IsDeviceLoaded = comm.IsDeviceLoading;
            if (comm.IsDeviceLoading)
            {
                comm.setConfigPanel = config;
            }
            if (config.ShowDialog() == true)
            {
                comm.Reset(Mod_Main.systemInfo.MachineAddr, Mod_Main.systemInfo.MachinePort);
                comm.IsYuanCheng = Mod_Main.systemInfo.IsYuanCheng;
                SmartMeterParamFrame.Communicate.IdentityType = Mod_Main.systemInfo.IdentityType;
                LstMeterState.ItemsSource = comm.MeterItems;
                Data_Meter.ItemsSource = comm.MeterItems;
                ShowState();            //显示状态栏状态
            }
        }

        /// <summary>
        /// 状态栏状态更新
        /// </summary>
        private void ShowState()
        {
            try
            {
                Txt_SET.Text = comm.IsDeviceLink ? "已联机" : "联机失败";

                Txt_Machine.Text = comm.IsMachineReady ? "已联机" : "联机失败";
            }
            catch { }
        }

        /// <summary>
        /// 加载指定名称的方案
        /// </summary>
        /// <param name="schemePath"></param>
        private void LoadScheme(string schemePath)
        {
            try
            {
                string mark;
                byte[] content;

                if (SchemeUtils.LoadSchemeBytes(out mark, out content, schemePath) == false)
                {
                    //MessageBox.Show("方案加载失败，不可识别的方案文件...","提示",MessageBoxButton.OK , MessageBoxImage.Exclamation);
                    return;
                }

                if (mark != HardDiskHelper.GetAllHardDiskSN())
                {
                    MessageBox.Show("方案校验错误，无法加载方案...", "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }

                faItems = new FACollection(content, SchemeCrypt.Instance);
            }
            catch (Exception e)
            {
                MessageBox.Show(string.Format("本地方案加载出错,错误原因：{0}...", e.Message), "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                System.IO.File.Delete(schemePath);
                faItems = new FACollection();
            }
            finally
            {
                if (faItems != null)
                {
                    Lst_PrjItems.ItemsSource = faItems;
                    this.tiFaItems.Header = "当前方案---" + faItems.FAName;
                }
            }
        }

        #endregion

    }

    public class ConverterMeterState : IValueConverter
    {

        #region IValueConverter 成员

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int inValue = 0;
            if (value is EnumMeterState)
            {
                inValue = (int)value;
            }
            else
            {
                int.TryParse(value.ToString(), out inValue);
            }

            string para = parameter.ToString();
            string[] arrValue = para.Split('|');
            return arrValue[inValue];
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

}
